package org.grow.secure.config;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import javax.servlet.Filter;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author: xwg
 * @CreateDate: 2022/5/26
 */
@EnableRedisHttpSession
@EnableWebSecurity
@EnableConfigurationProperties({SecureProperties.class})
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private final SecureProperties secureProperties;

    public SecurityConfig(SecureProperties secureProperties) {
        this.secureProperties = secureProperties;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().disable();
        http.csrf().disable();
        http.httpBasic().disable();
        if (secureProperties.getAnonymousUser()) {
            http.anonymous();
        } else {
            http.anonymous().disable();
        }
        http.logout().disable();
        http.formLogin().disable();
        http.exceptionHandling().authenticationEntryPoint(new BasicAuthenticationEntryPoint());
        http.authorizeRequests().anyRequest().permitAll();
    }

    @Bean
    public Random random() {
        return new Random();
    }

    @Bean
    public FilterRegistrationBean<Filter> corsBean() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.setMaxAge(3600L);
        corsConfiguration.addAllowedOriginPattern("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.setAllowedMethods
                (Stream.of("POST", "GET", "DELETE", "PUT", "OPTIONS")
                        .collect(Collectors.toList()));

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);
        CorsFilter corsFilter = new CorsFilter(source);
        FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();
        bean.setFilter(corsFilter);
        bean.setOrder(-1000);
        return bean;
    }
}
